package com.wash.shoes.domain.wx;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.wash.shoes.common.config.WxMaProperties;
import com.wash.shoes.exception.WashException;
import com.wash.shoes.oss.AliyunOSSUtil;
import lombok.extern.log4j.Log4j2;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @author lijianguo
 * @Date 15/03/2025 17:20
 * 微信的qr
 **/
@Log4j2
@Component
public class WxQrCodeComponent {

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private RestTemplate restTemplate;

    @Resource
    WxMaProperties wxMaProperties;

    // 获取token
    String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential";

    // 二维码
    String QR_UTL = "https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token={0}";

    @PostConstruct
    public void init() {
//        getQrCode("1212");
    }

    /**
     * 获取token
     */
    public String getWxToken() {

        String accessToken = (String) redisTemplate.opsForValue().get("accessToken");
        if (StrUtil.isBlank(accessToken)) {

            // 定义参数
            Map<String, String> params = new HashMap<>();
            params.put("appid", wxMaProperties.getConfigs().get(0).getAppid());
            params.put("secret", wxMaProperties.getConfigs().get(0).getSecret());
            // 使用 UriComponentsBuilder 构建包含参数的 URL
            UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(ACCESS_TOKEN_URL);
            for (Map.Entry<String, String> entry : params.entrySet()) {
                builder.queryParam(entry.getKey(), entry.getValue());
            }
            String url = builder.toUriString();
            // 发送 GET 请求
            ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
            // 输出响应结果
            log.info("response is {}", JSONObject.toJSON(response.getBody()));
            JSONObject jsonObject = JSONObject.parseObject(response.getBody());
            accessToken = jsonObject.getString("access_token");
            if (StrUtil.isBlank(accessToken)) {
                throw new WashException("accessToken get fail");
            }
            // 保存缓存
            redisTemplate.opsForValue().set("accessToken", accessToken, 7000, TimeUnit.SECONDS);
        }
        return accessToken;
    }

    /**
     * @param path
     * @return 生成二维码
     */
    public String getQrCode(String path) {

        String fullUrl = MessageFormat.format(QR_UTL, getWxToken());
        // 准备请求体
        Map<String, String> requestBody = new HashMap<>();
        requestBody.put("path", path);
        requestBody.put("width", "200");
        // 设置请求头，指定请求体的内容类型为 JSON 发送 POST 请求并获取响应
        byte[] imageBytes = fetchImageBuffer(fullUrl, JSONObject.toJSONString(requestBody));
        return generateQRCodeFromChar(imageBytes);
    }

    public static String generateQRCodeFromChar(byte[] imageBytes) {

        try {
            ByteArrayInputStream bais = new ByteArrayInputStream(imageBytes);
            // 使用 ImageIO 读取输入流并转换为 BufferedImage
            BufferedImage image = ImageIO.read(bais);
            // 保存二维码图片
            File newFile = new File(UUID.randomUUID() + ".png");
            ImageIO.write(image, "png", newFile);
            String url = AliyunOSSUtil.upload(newFile, "wxewm");
            FileUtil.del(newFile);
            return url;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return "";
    }

    public byte[] fetchImageBuffer(String urlStr, String requestBody) {
        try {
            HttpURLConnection connection = getHttpURLConnection(urlStr, requestBody);
            int responseCode = connection.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                InputStream inputStream = connection.getInputStream();
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                byte[] buffer = new byte[1024];
                int bytesRead;
                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    bos.write(buffer, 0, bytesRead);
                }
                inputStream.close();
                bos.close();
                return bos.toByteArray();
            } else {
                System.out.println("请求失败，响应码: " + responseCode);
            }
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    private HttpURLConnection getHttpURLConnection(String urlStr, String requestBody) throws IOException {
        URL url = new URL(urlStr);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("POST");
        connection.setDoOutput(true); // 允许输出，即发送请求体
        connection.setRequestProperty("Content-Type", "application/json"); // 设置请求头的 Content-Type，根据实际情况修改

        // 写入请求体
        try (OutputStream os = connection.getOutputStream();
             BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, StandardCharsets.UTF_8))) {
            writer.write(requestBody);
            writer.flush();
        }
        return connection;
    }


}
